# coding:utf-8
import json
import time
from datetime import timedelta, datetime

from common.constant import IM_MESSAGE
from common.models import model_factory, DemandStatus, ParticStatus
from common.producer import Producer
from common.schedule.demand_utils import clear_cache
from common.schedule.opc_celery import celery_app
from common.utils import DB


@celery_app.task(name='master_dispatch_handle', bind=True, max_retries=3, default_retry_delay=5)
def master_dispatch_handle(self, demand_id):
    """
    created by chenhj at 02/01/2018
    主人派单项目处理
    """
    print('主人派单项目流程, 项目id: {}'.format(demand_id))
    now = datetime.utcnow()
    try:

        with DB() as session:

            demand = model_factory.demand.get_by_id(session, demand_id)

            # 若该企业下无人抢单, 则派单的用户记录下超时
            dispatch_success_recs = session.query(model_factory.partic).filter(
                model_factory.partic.demand_status == DemandStatus.MASTER_DISPATCHING.value,
                model_factory.partic.status == ParticStatus.SUCCEED.value,
                model_factory.partic.published_count == demand.published_count,
                model_factory.partic.demand_id == demand.id
            ).all()
            enterprise_ids = [x.enterprise_id for x in dispatch_success_recs]
            session.query(model_factory.partic).filter(
                model_factory.partic.demand_status == DemandStatus.MASTER_DISPATCHING.value,
                model_factory.partic.status == ParticStatus.WAITING.value,
                model_factory.partic.published_count == demand.published_count,
                model_factory.partic.demand_id == demand.id,
                model_factory.partic.enterprise_id.notin_(enterprise_ids)
            ).update({
                'partic_timeout': True
            }, synchronize_session='fetch')

            # 若项目已被设置为无效/圆满完成, 则不往下走了
            if demand.status in (DemandStatus.DONE.value, DemandStatus.INVALID.value):
                return

            # 若无, 则进入下一步, 并通知工程商
            demand.is_dispatch = True
            demand.published_at = int(time.time())
            demand_status = DemandStatus.DISPATCHING.value

        clear_cache(demand_id)
        im_msg_producer = Producer(IM_MESSAGE)
        im_msg_producer.send(json.dumps({
            'func': 'new_notify',
            'args': [],
            'kwargs': {
                'demand_id': demand_id,
                'demand_status': demand_status
            }
        }))
    except Exception as exc:
        self.retry(exc=exc, expires=now + timedelta(seconds=60 * 2))


@celery_app.task(name='dispatch_demand_handle', bind=True, max_retries=3, default_retry_delay=5)
def dispatch_demand_handle(self, demand_id):
    """
    created by chenhj at 02/01/2018
    派单项目处理
    """
    print('派单项目流程, 项目id: {}'.format(demand_id))
    now = datetime.utcnow()
    try:

        with DB() as session:

            demand = model_factory.demand.get_by_id(session, demand_id)

            # 若该企业下无人抢单, 则派单的用户记录下超时
            dispatch_success_recs = session.query(model_factory.partic).filter(
                model_factory.partic.demand_status == DemandStatus.DISPATCHING.value,
                model_factory.partic.status == ParticStatus.SUCCEED.value,
                model_factory.partic.published_count == demand.published_count,
                model_factory.partic.demand_id == demand.id
            ).all()
            enterprise_ids = [x.enterprise_id for x in dispatch_success_recs]
            session.query(model_factory.partic).filter(
                model_factory.partic.demand_status == DemandStatus.DISPATCHING.value,
                model_factory.partic.status == ParticStatus.WAITING.value,
                model_factory.partic.published_count == demand.published_count,
                model_factory.partic.demand_id == demand.id,
                model_factory.partic.enterprise_id.notin_(enterprise_ids)
            ).update({
                'partic_timeout': True
            }, synchronize_session='fetch')

            # 若项目已被设置为无效/圆满完成, 则不往下走了
            if demand.status in (DemandStatus.DONE.value, DemandStatus.INVALID.value):
                return

            # 若无, 则进入下一步, 并通知工程商
            demand.is_dispatch = False
            demand.published_at = int(time.time())
            demand_status = DemandStatus.BRONZE_MEDAL_DISCOUNT.value

        clear_cache(demand_id)
        im_msg_producer = Producer(IM_MESSAGE)
        im_msg_producer.send(json.dumps({
            'func': 'new_notify',
            'args': [],
            'kwargs': {
                'demand_id': demand_id,
                'demand_status': demand_status
            }
        }))
    except Exception as exc:
        self.retry(exc=exc, expires=now + timedelta(seconds=60 * 2))


@celery_app.task(name='demand_new_notify_task')
def demand_new_notify_task(demand_id):
    """
    create by ld_wu 2018-04-11
    订单新消息提醒任务(暂时为铜牌一口价后，进入竞价模式的消息通知)
    """
    with DB() as session:
        demand = model_factory.demand.get_by_id(session, demand_id)
        # 项目状态为非铜牌一口价则不会继续发消息
        if demand.status != DemandStatus.BRONZE_MEDAL_DISCOUNT.value:
            return

        # 若有铜牌一口价锁定用户, 则直接更新项目状态为抢单结束
        had_locked = model_factory.partic.get_by_args(
            session,
            demand_id=demand_id,
            follow_type=1,
            demand_status=DemandStatus.BRONZE_MEDAL_DISCOUNT.value
        )
        if had_locked:
            demand.status = DemandStatus.COMPETE_DONE.value
            return

        # 若无, 则进入首次竞价模式, 并通知工程商
        demand_status = DemandStatus.ONGOING.value
        demand.is_dispatch = False

    clear_cache(demand_id)
    # 前面都没问题, 再进行推送
    im_msg_producer = Producer(IM_MESSAGE)
    im_msg_producer.send(json.dumps({
        'func': 'new_notify',
        'args': [],
        'kwargs': {
            'demand_id': demand_id,
            'demand_status': demand_status
        }
    }))
